package org.ns.longhttp.selector.requestmapper;

import org.ns.longhttp.ThreanName;
import org.ns.longhttp.config.ServerConfig;
import org.ns.longhttp.wrapper.GetRequestWrapper;
import org.ns.longhttp.wrapper.MapWrapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public class RequestMappingQueue {

    public static final int DEFAULT_AWAIT_TIMEOUT = 15;

//    private final static RequestMappingQueue instance = new RequestMappingQueue();
//
//    public static RequestMappingQueue getInstance() {
//        return instance;
//    }

    private MapWrapper<String, MappingQueueEntry> mappingMap = new MapWrapper<>();
    private ScheduledExecutorService requestClearListener = Executors.newScheduledThreadPool(1, new ThreanName("requestClearListener", true));
    private ExecutorService requestClearThread;

    public RequestMappingQueue() {

    }

    private void init() {
        requestClearListener.scheduleWithFixedDelay(this::bossRun, 0, 500, TimeUnit.MILLISECONDS);
    }
    public void add(GetRequestWrapper requestWrapper) {
        String url = requestWrapper.getUrl();

        MappingQueueEntry mappingQueueEntry = getMappingQueueEntry(url);
        int second = requestWrapper.getAwaitTimeout(DEFAULT_AWAIT_TIMEOUT);
        mappingQueueEntry.add(requestWrapper, second);
    }

    public MappingQueueEntry getMappingQueueEntry(String url) {
        MappingQueueEntry mappingQueueEntry = mappingMap.get(url, MappingQueueEntry::new);
        return mappingQueueEntry;
    }

    public List<GetRequestWrapper> getRequestWrappers(String url) {
        List<GetRequestWrapper> requestWrappers = getMappingQueueEntry(url).getRequestWrappers();
        return requestWrappers;
    }
    private void bossRun () {
        try {
            List<Future<?>> list = new ArrayList<>();
            for (MappingQueueEntry value : mappingMap.values()) {
                Future<?> future = requestClearThread.submit(value::closeInvalid);
                list.add(future);
            }
            for (Future<?> future : list) {
                try {
                    future.get();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public void config(ServerConfig serverConfig) {
        // 初始化请求过期处理线程数，用于清理超时的请求。
        int requestClearThreadSize = serverConfig.getRequestClearThreadSize();
        requestClearThread = Executors.newFixedThreadPool(requestClearThreadSize, new ThreanName("requestClearThread", true));
        // 初始化请求映射复用队列
        this.init();
    }
}
